package com.jiangnan.view;

import com.jiangnan.constants.Constants;
import com.jiangnan.constants.TopButton;
import com.jiangnan.model.TableData;
import com.jiangnan.service.PacketService;
import com.jiangnan.utils.*;
import jpcap.packet.Packet;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 *
 * 主面板
 *
 * @author chenliang
 * @email wschenliang@aliyun.com
 */
public class HomeJPanel extends JPanel {
    private final PacketService packetService = PacketService.newInstance();
    private final JFrame jFrame;
    private final JButton startButton, stopButton, openButton,
            fileAppendButton, saveButton, saveAsJsonButton,
            restartButton, optionButton, clearButton, resortButton;
    private final JTable jTable;
    private final JTextArea logArea, infoArea, binArea;
    private final JComboBox<String> deviceBox;

    public HomeJPanel(JFrame jFrame) {
        this.jFrame = jFrame;
        this.setLayout(new BorderLayout(2,2));//设置面板 borderLayout分为东南西北中
        //-------------------------------最先加载日志域，用来记录输出---------------------------------------------------------------
        logArea = SwingUtil.getBottomArea("log:",false);
        LogUtils.setLogComponent(logArea);//有了logArea后，将变量注入全局
        infoArea = SwingUtil.getBottomArea(null,false);//底部输出文本域
        binArea = SwingUtil.getBottomArea(null,false);//二进制文本域

        //----------------------------------顶部按钮和标签------------------------------------------------------------
        startButton = SwingUtil.getTopButton(TopButton.START);//开始按钮
        stopButton = SwingUtil.getTopButton(TopButton.STOP);//停止按钮
        openButton = SwingUtil.getTopButton(TopButton.OPEN);//读取按钮
        fileAppendButton = SwingUtil.getTopButton(TopButton.FILE_APPEND);//文件添加
        saveButton = SwingUtil.getTopButton(TopButton.SAVE);//保存按钮
        saveAsJsonButton = SwingUtil.getTopButton(TopButton.SAVE_AS_JSON);//保存json格式按钮
        restartButton = SwingUtil.getTopButton(TopButton.RESTART);//重启按钮
        optionButton = SwingUtil.getTopButton(TopButton.OPTIONS);//设置按钮
        clearButton = SwingUtil.getTopButton(TopButton.CLOSE);//清除按钮
        resortButton = SwingUtil.getTopButton(TopButton.RESORT);//重置按钮
        deviceBox = SwingUtil.getComboBox(JpcapUtil.getDeviceIp());
        //-----------------------------------中间表格-----------------------------------------------------------
        jTable = SwingUtil.getJTable(TableData.getTitle());
        JTableUtil.setJTableComponent(jTable);//注入全局就可以到处调用了

        //初始化
        initComponent();
        //----------------------------------------------------------------------------------------------
        this.add(getTopPanel(), BorderLayout.NORTH);
        this.add(getMidPanel(),BorderLayout.CENTER);
        this.add(getBottomPanel(),BorderLayout.SOUTH);
        this.add(getLeftPanel(), BorderLayout.WEST);
    }

    private void initComponent() {
        startButton.addActionListener(new StartAction());
        restartButton.addActionListener(new StartAction().restart(true));
        stopButton.addActionListener(new StopAction());
        openButton.addActionListener(new FileOpenAction());
        fileAppendButton.addActionListener(new FileOpenAction().append(true));
        saveButton.addActionListener(new SaveAction(Constants.SAVA_FILE_PCAP));
        saveAsJsonButton.addActionListener(new SaveAction(Constants.SAVA_FILE_JSON));
        optionButton.addActionListener(new OptionAction());
        clearButton.addActionListener(new ClearAction());
        resortButton.addActionListener(new ResortAction());
        jTable.addMouseListener(new JTableMouse());
        jTable.getColumnModel().getColumn(0).setMinWidth(65);
        jTable.getColumnModel().getColumn(0).setMaxWidth(75);
        jTable.getColumnModel().getColumn(1).setMinWidth(120);
        jTable.getColumnModel().getColumn(1).setMaxWidth(140);
        jTable.getColumnModel().getColumn(2).setMinWidth(150);
        jTable.getColumnModel().getColumn(2).setMaxWidth(200);
        jTable.getColumnModel().getColumn(3).setMinWidth(150);
        jTable.getColumnModel().getColumn(3).setMaxWidth(200);
        jTable.getColumnModel().getColumn(4).setMaxWidth(70);
        jTable.getColumnModel().getColumn(5).setMaxWidth(60);
        SwingUtil.EnableComponent(false, stopButton, restartButton, saveButton, saveAsJsonButton, clearButton, resortButton);
    }

    //设置
    private class OptionAction extends AbstractAction {
        private static final long serialVersionUID = -8484437945315195401L;
        @Override
        public void actionPerformed(ActionEvent e) {
            OptionDialog optionDialog = new OptionDialog();
            optionDialog.setLocationRelativeTo(jFrame);
        }
    }
    //保存
    private class SaveAction extends AbstractAction {
        private static final long serialVersionUID = -7782397803679376340L;

        private String saveModel;

        public SaveAction(String saveModel) {
            this.saveModel = saveModel;
        }

        public SaveAction saveModel(String saveModel) {
            this.saveModel = saveModel;
            return this;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            packetService.saveFile(saveModel, jFrame);
        }
    }
    //重排
    private class ResortAction extends AbstractAction {
        private static final long serialVersionUID = -3502483405028510104L;

        @Override
        public void actionPerformed(ActionEvent e) {
            resortButton.setEnabled(false);
            JTableUtil.resortTable();
            LogUtils.log("重排成功");
            resortButton.setEnabled(true);
        }
    }
    //清除
    private class ClearAction extends AbstractAction {
        private static final long serialVersionUID = 7365100469415589175L;

        @Override
        public void actionPerformed(ActionEvent e) {
            DefaultTableModel model = (DefaultTableModel) jTable.getModel();
            model.setRowCount(0);
            PacketUtil.init();
            SwingUtil.EnableComponent(false, saveButton, saveAsJsonButton);
        }
    }
    //打开文件
    private class FileOpenAction extends AbstractAction {

        private static final long serialVersionUID = -1398516117457976118L;

        private boolean isAppend = false;

        public FileOpenAction append(boolean append) {
            isAppend = append;
            return this;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            packetService.openFileAsyn(isAppend, jFrame);
            if (jTable.getModel().getRowCount() > 0) {
                SwingUtil.EnableComponent(true, clearButton, saveButton, saveAsJsonButton, resortButton);
            }
        }
    }
    //停止
    private class StopAction extends AbstractAction {
        private static final long serialVersionUID = -8654507712257715733L;

        @Override
        public void actionPerformed(ActionEvent e) {
            packetService.stopCaptureLoop();
            SwingUtil.EnableComponent(true, startButton, deviceBox, openButton, fileAppendButton, optionButton);
            stopButton.setEnabled(false);
            DefaultTableModel model = (DefaultTableModel) jTable.getModel();
            //判断有没有数据，如果有数据，保存按钮要亮起来
            if (model.getRowCount() > 0) {
                SwingUtil.EnableComponent(true, saveButton, saveAsJsonButton, restartButton, resortButton, clearButton);
            }

        }
    }
    //启动
    private class StartAction extends AbstractAction {
        private static final long serialVersionUID = 2900883951427726532L;

        private boolean restart = false;

        public StartAction restart(boolean restart) {
            this.restart = restart;
            return this;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String deviceIp = (String) deviceBox.getSelectedItem();
            if (restart) {
                LogUtils.log("重启中...");
                JTableUtil.clearJTable();
            }
            packetService.startCaptureLoop(deviceIp);
            SwingUtil.EnableComponent(false, startButton, deviceBox, restartButton, saveButton,
                    saveAsJsonButton, optionButton, openButton, fileAppendButton, clearButton);
            stopButton.setEnabled(true);
        }
    }
    //表格点击事件
    private class JTableMouse extends MouseAdapter {
        @Override
        public void mouseClicked(MouseEvent e) {
            int selectedRow = jTable.getSelectedRow();
            String infoStr = (String) jTable.getValueAt(selectedRow, 6);
            String protoStr = (String) jTable.getValueAt(selectedRow, 4);
            String modelStr = (String) jTable.getValueAt(selectedRow, 7);
            String infoText = packetService.getInfoString2(modelStr, infoStr);
            infoArea.setText(infoText);
            infoArea.setCaretPosition(0);//每点击一次，要调整info的滚动，横竖都在第一行
            Packet packet = PacketUtil.convertString2Packet(infoStr, protoStr);
            String binString = PacketUtil.toBinString(packet.header, packet.data);
            binArea.setText(binString);
            binArea.setCaretPosition(0);
        }
    }

    private JPanel getTopPanel() {
        JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        jPanel.setBackground(Color.WHITE);
        jPanel.add(startButton);
        jPanel.add(stopButton);
        jPanel.add(restartButton);
        jPanel.add(openButton);
        jPanel.add(fileAppendButton);
        jPanel.add(saveButton);
        jPanel.add(saveAsJsonButton);
        jPanel.add(clearButton);
        jPanel.add(optionButton);
        jPanel.add(resortButton);
        jPanel.add(deviceBox);
        return jPanel;
    }
    private JScrollPane getLeftPanel() {
        Box box = Box.createVerticalBox();
        box.add(SwingUtil.getCheckBox("DDoS检测"));//未完善
        box.add(SwingUtil.getCheckBox("流量过滤"));//未完善
        JScrollPane jPanel = new JScrollPane(box);
        jPanel.setPreferredSize(new Dimension(150, 0));//宽度起作用，长度固定好了
        return jPanel;
    }
    private JPanel getBottomPanel() {
        JPanel jPanel = new JPanel(new GridLayout(1,3));
        JScrollPane infoJScrollPane = new JScrollPane(infoArea);
        infoJScrollPane.setPreferredSize(new Dimension(0,350));//高度起作用，宽度固定好了

        JScrollPane binJScrollPane = new JScrollPane(binArea);
        binJScrollPane.setPreferredSize(new Dimension(0,350));//高度起作用，宽度固定好了

        JScrollPane logJScrollPane = new JScrollPane(logArea);
        logJScrollPane.setPreferredSize(new Dimension(0, 350));//宽度起作用，长度固定好了

        jPanel.add(infoJScrollPane);
        jPanel.add(binJScrollPane);
        jPanel.add(logJScrollPane);
        return jPanel;
    }

    private JScrollPane getMidPanel() {
        JScrollPane jScrollPane = new JScrollPane(jTable);
        jScrollPane.setPreferredSize(new Dimension(600, 0));
        JScrollBar vScrollBar = jScrollPane.getVerticalScrollBar();
        vScrollBar.setValue(0);//设置成自动滚动最后一条
        JScrollBar hScrollBar = jScrollPane.getHorizontalScrollBar();
        hScrollBar.setValue(hScrollBar.getMaximum());
        return jScrollPane;
    }
}
